﻿' BasecampVB - http://www.tidbitsandtangents.com
' Copyright (c) 2009
' by Rusty S. Swayne
'
' Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
' documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
' the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
' to permit persons to whom the Software is furnished to do so, subject to the following conditions:
'
' The above copyright notice and this permission notice shall be included in all copies or substantial portions 
' of the Software.
'
' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
' INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
' DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
' SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
' SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
' WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
' THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Imports System.Net
Imports System.IO
Imports System.Text
Imports System.Xml

Namespace DAL

    Public MustInherit Class ApiAccess

        ''' <summary>
        ''' Returns Basecamp API call response as a XmlDocument object
        ''' </summary>
        Public Function GetXmlDocumentResponse(ByVal requestString As String, Optional ByVal method As String = "GET", Optional ByVal requestXml As String = "") As XmlDocument
            Dim doc As New XmlDocument
            doc.LoadXml(GetResponseFromBasecampAPI(requestString, method, requestXml))
            Return doc
        End Function

        ''' <summary>
        ''' Returns Basecamp API call response as a String
        ''' </summary>
        Public Function GetResponse(ByVal requestString As String, Optional ByVal method As String = "GET", Optional ByVal requestXml As String = "") As String
            Return GetResponseFromBasecampAPI(requestString, method, requestXml)
        End Function

        ''' <summary>
        ''' Helper function which executes the actual Basecamp REST API call and returns a string
        ''' </summary>
        Private Function GetResponseFromBasecampAPI(ByVal requestString As String, ByVal method As String, ByVal requestXml As String) As String
            Dim Host As New Uri(String.Format(basecamp_url & requestString))
            Dim resource_xml As String = String.Empty
            Dim request As HttpWebRequest = HttpWebRequest.Create(Host)
            request.ContentType = "application/xml"
            request.Accept = "application/xml"
            request.ServicePoint.Expect100Continue = False
            request.Headers.Add("Authorization", String.Format("Basic {0}", Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", api_user_name, api_password)))))
            request.Method = method

            If Not String.IsNullOrEmpty(requestXml) And Not String.Equals(method.ToUpper, "GET") Then
                Using sw As New StreamWriter(request.GetRequestStream())
                    sw.WriteLine(requestXml)
                End Using
            End If

            Try
                Dim response As HttpWebResponse = request.GetResponse()
                If Not String.IsNullOrEmpty(response.Headers("Location")) Then Return response.Headers("Location")

                If response IsNot Nothing Then
                    Using sr As New StreamReader(response.GetResponseStream())
                        resource_xml = sr.ReadToEnd
                    End Using
                End If
            Catch ex As WebException
                If ex.Status = WebExceptionStatus.ProtocolError Then
                    resource_xml = "<error><code>" & CType(ex.Response, HttpWebResponse).StatusCode & "</code><message>" & ex.Message & "</message></error>"
                End If

            End Try
            Return resource_xml
        End Function


        ''' <summary>
        ''' Returns value of XmlNode InnerText as DateTime or Nothing
        ''' </summary>
        Protected Shared Function GetChildNodeInnerTextAsDateTime(ByVal node As XmlNode, ByVal localname As String) As DateTime
            Dim dt As String = GetChildNodeInnerTextAsString(node, localname)
            If Not String.IsNullOrEmpty(dt) Then
                Return CType(dt, DateTime)
            Else
                Return Nothing
            End If
        End Function

        ''' <summary>
        ''' Converts a DateTime to API QueryString specified format YYYYMMDD
        ''' </summary>
        Protected Shared Function ConvertDateTimeToQueryStringFormat(ByVal dt As DateTime) As String
            Return String.Format("{0}{1}{2}", dt.Year, dt.Month.ToString.PadLeft(2, "0"), dt.Day.ToString.PadLeft(2, "0"))
        End Function

        ''' <summary>
        ''' Returns value of XmlNode InnerText as Boolean
        ''' </summary>
        Protected Shared Function GetChildNodeInnerTextAsBoolean(ByVal node As XmlNode, ByVal localname As String) As Boolean
            Return CType(GetChildNodeInnerTextAsString(node, localname), Boolean)
        End Function

        ''' <summary>
        ''' Returns value of XmlNode InnerText as Double
        ''' </summary>
        Protected Shared Function GetChildNodeInnerTextAsDouble(ByVal node As XmlNode, ByVal localname As String) As Double
            Dim value As String = GetChildNodeInnerTextAsString(node, localname)
            If String.IsNullOrEmpty(value) Then value = 0
            Return CType(value, Double)
        End Function

        ''' <summary>
        ''' Returns value of XmlNode InnerText as Integer
        ''' </summary>
        Protected Shared Function GetChildNodeInnerTextAsInt(ByVal node As XmlNode, ByVal localname As String) As Integer
            Dim value As String = GetChildNodeInnerTextAsString(node, localname)
            If String.IsNullOrEmpty(value) Then value = 0
            Return CType(value, Integer)
        End Function

        ''' <summary>
        ''' Returns value of XmlNode InnerText as String
        ''' </summary>
        Protected Shared Function GetChildNodeInnerTextAsString(ByVal node As XmlNode, ByVal localname As String) As String
            Try
                Return node.SelectSingleNode(localname).InnerText.Trim
            Catch ex As Exception
                Return String.Empty
            End Try
        End Function


        Private _basecamp_url As String
        Protected Property basecamp_url() As String
            Get
                Return _basecamp_url
            End Get
            Set(ByVal value As String)
                _basecamp_url = value
            End Set
        End Property

        Private _api_user_name As String
        Protected Property api_user_name() As String
            Get
                Return _api_user_name
            End Get
            Set(ByVal value As String)
                _api_user_name = value
            End Set
        End Property


        Private _api_password As String
        Protected Property api_password() As String
            Get
                Return _api_password
            End Get
            Set(ByVal value As String)
                _api_password = value
            End Set
        End Property



    End Class

End Namespace